package widget.pull;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Message;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import library.logger.Logger;
import library.utils.DisplayUtil;
import library.utils.InnerHandler;

/**
 * Created by Mr.Fan on 2016-6-16.
 */
public abstract class IPullView extends LinearLayout {

    public static final int STATE_NULL = -2;
    public static final int STATE_HIDE = -1; //隐藏
    public static final int STATE_PULL = 0;//正在拉动，距离低于阈值
    public static final int STATE_HOLD = 1;//正在拉动，距离达到阈值
    public static final int STATE_REFRESH = 2;//正在刷新
    public static final int STATE_FINISH = 3;//刷新完成或正在释放
    public static final int STATE_AUTO_LOAD = 4; //自动加载

    public int defaultHeight;

    private final StateHandler handler = new StateHandler(this);
    private LinearLayout contentView;
    private int state = STATE_HIDE;
    private int lastState = state;
    private Object param = null;

    public IPullView(Context context) {
        super(context);
        __init();
    }

    public IPullView(Context context, AttributeSet attrs) {
        super(context, attrs);
        __init();
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public IPullView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        __init();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public IPullView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        __init();
    }

    private void __init() {
        defaultHeight = DisplayUtil.dp2px(58);
        final int minHeight = getMinHeight();
        setMinimumHeight(minHeight > 0 ? minHeight : defaultHeight);

        final LinearLayout ll = new LinearLayout(getContext());
        addView(ll, new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT));
        onInitContainerLayout(ll);
        contentView = ll;
    }

    protected LinearLayout getContentView() {
        return contentView == null ? this : contentView;
    }

    protected abstract void onInitContainerLayout(LinearLayout container);

    protected abstract int getMinHeight();

    protected abstract boolean isFloating();

    protected abstract void onAutoLoad();

    protected abstract void onHide();

    protected abstract void onPull(float percent);

    protected abstract void onHold();

    protected abstract void onRefresh();

    protected abstract void onFinish();

    protected abstract void onFinish(boolean result);


    protected int getLastState() {
        return lastState;
    }

    protected int getState() {
        return state;
    }

    protected void setState(int state, Object param) {
        if (this.state == state && this.param == param)
            return;
        this.lastState = this.state;
        this.state = state;
        this.param = param;
        Message msg = handler.obtainMessage(state, param);
        handler.sendMessage(msg);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        handler.removeCallbacksAndMessages(null);
    }


    public void setDebuggable(boolean allowLog) {
        this.handler.setDebuggable(allowLog);
    }

    private static class StateHandler extends InnerHandler<IPullView> {

        private boolean allowLog = false;

        public StateHandler(IPullView object) {
            super(object);
        }

        public void setDebuggable(boolean allowLog) {
            this.allowLog = allowLog;
        }

        private void debug(Object... info) {
            if (allowLog)
                Logger.simple(info);
        }

        @Override
        protected void handleMessage(Message msg, IPullView view) {
            int state = msg.what;
            Object param = msg.obj;
            if (state == STATE_HIDE) {
                if (view.getVisibility() != GONE)
                    view.setVisibility(GONE);
            } else if (view.getVisibility() != VISIBLE) {
                view.setVisibility(VISIBLE);
            }
            switch (state) {
                case STATE_HIDE:
                    debug("onHide()");
                    view.onHide();
                    break;
                case STATE_AUTO_LOAD:
                    debug("onAutoLoad()");
                    view.onAutoLoad();
                    break;
                case STATE_PULL:
                    float percent = param != null ? Float.parseFloat(param.toString()) : 1f;
                    debug("onPull(" + percent + ")");
                    view.onPull(percent);
                    break;
                case STATE_HOLD:
                    debug("onHold()");
                    view.onHold();
                    break;
                case STATE_REFRESH:
                    debug("onRefresh()");
                    view.onRefresh();
                    break;
                case STATE_FINISH:
                    if (param != null) {
                        Boolean result = Boolean.parseBoolean(param.toString());
                        debug("onFinish(" + result + ")");
                        view.onFinish(result);
                    } else {
                        debug("onFinish()");
                        view.onFinish();
                    }
                    break;
            }
        }

    }

}
